﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProgNetComponentsDx.Forms;
using ProgNetComponents.Interfaces;
using ProgNetComponentsDx.Options;
using Wydatki.Init;
using Wydatki.Setup.DataSets;
using Wydatki.Tools.Lotto;

namespace Wydatki.Setup.Lotto
{
    public partial class LottoStatystykiGlobalne : MyBaseSqlCeGridForm
    {
        public LottoStatystykiGlobalne()
        {
            InitializeComponent();
        }
        protected override void OnLoad()
        {
            if (!this.IsDesignMode())
            {
                this.Controls.Remove(this.gcMain);
                gcMain.Dock = DockStyle.Fill;
                splitContainerControl1.Panel1.Controls.Add(this.gcMain);
            }
            base.OnLoad();
        }
        protected override bool ValidateAll()
        {
            bool result = base.ValidateAll();
            if (result)
            {
                string type;
                ActionLottoBase action;
                foreach (DataRow r in lottoStatystykiGlobalneDataSet1.STP_LOTTO_STATYSTYKI_GLOBALNE.Rows)
                {
                    r.ClearErrors();
                    type = r["STP_LSG_TYP"].AsString();
                    action = ActionLottoBase.GetAction(type);
                    if (action == null)
                    {
                        r.SetColumnError("STP_LSG_TYP", "Zły typ");
                        result = false;
                    }
                    else
                    {
                        result = action.ValidateParams(r);
                    }
                }
            }
            return result;
        }
        LottoStatystykiGlobalneDataSet copyDs = null;
        private FormBackgroundWorkMultiThread multiThreadForm;

        object lockDs = new object();
        int max = 13983816;
        bool multiThread;
        DataRow[] rows;

        private void bbiWyliczBrakujace_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            FinishEdit();
            if (!ValidateAll())
            {
                this.ShowDxInfoDialog("Błąd walidacji.");
                return;
            }

            copyDs = lottoStatystykiGlobalneDataSet1.Copy() as LottoStatystykiGlobalneDataSet;
            rows = copyDs.STP_LOTTO_STATYSTYKI_GLOBALNE.Select("LICZ = 1");
            foreach (DataRow r in rows)
            {
                r["STP_LSG_ILOSC"] = DBNull.Value;
                r["STP_LSG_PROCENTOWO"] = DBNull.Value;
            }

            multiThread = OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Lotto.UzywajWieluWatkow);

            if (rows.Length < 1)
            {
                this.ShowDxInfoDialog("Wybierz wiersze,");
                return;
            }

            multiThreadForm = new FormBackgroundWorkMultiThread("Szacowanie ...");
            multiThreadForm.BackgroundControl.SupportCancelation = true;
            multiThreadForm.BackgroundControl.ProgressType = ProgressType.Percentage;
            multiThreadForm.BackgroundControl.MaxProgress = (max);
            if (multiThread)
            {
                Dictionary<int,int> dic = new Dictionary<int, int>();
                dic.Add(1, 5);
                dic.Add(5, 13);
                dic.Add(13, 23);
                dic.Add(23, 35);
                dic.Add(35, 45);
                foreach (KeyValuePair<int,int> kvp in dic)
                {
                    multiThreadForm.AddAction(new Action<int, int>(Szacuj), new object[] { kvp.Key, kvp.Value });
                }
            }
            else
            {
                multiThreadForm.AddAction(new Action<int, int>(Szacuj), new object[] { 1, 45 });
            }
            progressReporter1.Form = multiThreadForm;
            progressReporter1.Start();
            DialogResult dlg = multiThreadForm.ShowDialog();
            progressReporter1.Stop();
            switch (dlg)
            {
                case System.Windows.Forms.DialogResult.Cancel:
                    this.ShowDxInfoDialog("Przerwa na życzenie użytkownika");
                    break;
                case System.Windows.Forms.DialogResult.Abort:
                    this.ShowDxErrorDialog("Błąd wyliczania.");
                    break;
                case System.Windows.Forms.DialogResult.OK:
                    lottoStatystykiGlobalneDataSet1.Clear();
                    lottoStatystykiGlobalneDataSet1.AcceptChanges();
                    lottoStatystykiGlobalneDataSet1.Merge(copyDs);
                    break;
            }
        }

        private ActionLottoBase GetAction(string type)
        {
            return ActionLottoBase.GetAction(type);
        }

        private void Szacuj(int minNum, int maxNum)
        {
            List<int> list = new List<int>();
            for (int l=1; l < 50; l++)
                list.Add(l);
            List<int> kombinacja = new List<int>();
            ActionLottoBase action;
            Dictionary<DataRow, int[]> dic = new Dictionary<DataRow, int[]>();
            Dictionary<DataRow, int> results = new Dictionary<DataRow, int>();
            foreach (DataRow r in rows)
            {
                dic.Add(r, new int[]{r["STP_LSG_X"].AsInt(-1), 
                    r["STP_LSG_Y"].AsInt(-1), 
                    r["STP_LSG_Z"].AsInt(-1)});
                results.Add(r, 0);
            }
            for (int l1=minNum; l1 < maxNum; l1++)
            {
                for (int l2 = l1 + 1; l2 < 46; l2++)
                {
                    for (int l3 = l2 + 1; l3 < 47; l3++)
                    {
                        for (int l4 = l3 + 1; l4 < 48; l4++)
                        {
                            for (int l5 = l4 + 1; l5 < 49; l5++)
                            {
                                for (int l6 = l5 + 1; l6 < 50; l6++)
                                {
                                    if (multiThreadForm.BackgroundControl.IsCanceling)
                                        return;
                                    lock (lockDs)
                                    {
                                        progressReporter1.Progress++;
                                    }
                                    kombinacja.Clear();
                                    kombinacja.AddRange(new int[] { l1, l2, l3, l4, l5, l6 });
                                    foreach (KeyValuePair<DataRow, int[]> kvp in dic)
                                    {
                                        action = GetAction(kvp.Key["STP_LSG_TYP"].ToString());
                                        if (action != null)
                                        {
                                            lock (lockDs)
                                            {
                                                if (action.LiczbySpelniajaWarunki(kombinacja, kvp.Value[0], kvp.Value[1], kvp.Value[2]))
                                                {
                                                    results[kvp.Key] += 1;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            lock (lockDs)
            {
                foreach (KeyValuePair<DataRow, int> kvp in results)
                {
                    kvp.Key["STP_LSG_ILOSC"] = kvp.Key["STP_LSG_ILOSC"].AsInt(0) + kvp.Value;
                    kvp.Key["STP_LSG_PROCENTOWO"] = kvp.Key["STP_LSG_ILOSC"].AsDecimal() / max.AsDecimal();
                    if (!multiThread)
                        kvp.Key["LICZ"] = false;
                }
            } 
        }

        private void modeProvider1_CustomGetModes(object sender, ProgNetComponentsDx.Mode.CustomModeSettingsEventArgs e)
        {
            if (sender == colSTP_LSG_X ||
                   sender == colSTP_LSG_Y ||
                   sender == colSTP_LSG_Z )
            {
                if (modeProvider1.CurrentMode == ProgNetComponentsDx.Enums.FormMode.Edit)
                {
                    if (!e.Row.CanRead())
                    {
                        e.IsReadOnly = true;
                        return;
                    }
                    
                    ActionLottoBase action = GetAction(e.Row["STP_LSG_TYP"].AsString());
                    if (action == null)
                    {
                        e.IsReadOnly = true;
                    }
                    else
                    {
                        if (sender == colSTP_LSG_X)
                            e.IsReadOnly = action.IsColReadOnly("X");
                        else if (sender == colSTP_LSG_Y)
                            e.IsReadOnly = action.IsColReadOnly("Y");
                        else if (sender == colSTP_LSG_Z)
                            e.IsReadOnly = action.IsColReadOnly("Z");
                    }
                }
                else
                {
                    e.IsReadOnly = true;
                }
            }
        }

        private void btnOdznacz_Click(object sender, EventArgs e)
        {
            DataRow[] rows = lottoStatystykiGlobalneDataSet1.STP_LOTTO_STATYSTYKI_GLOBALNE.Select();
            foreach (DataRow r in rows)
                r["LICZ"] = false;
        }

        private void btnZaznacz_Click(object sender, EventArgs e)
        {
            DataRow[] rows = lottoStatystykiGlobalneDataSet1.STP_LOTTO_STATYSTYKI_GLOBALNE.Select("STP_LSG_ILOSC IS NULL");
            foreach (DataRow r in rows)
                r["LICZ"] = true;
        }

        private void gvMain_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            if (e.Column == colSTP_LSG_X ||
                e.Column == colSTP_LSG_Y ||
                e.Column == colSTP_LSG_Z)
            {
                gvMain.SetRowCellValue(e.RowHandle, colSTP_LSG_PROCENTOWO, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colSTP_LSG_ILOSC, DBNull.Value);
            }
            else if(e.Column == colSTP_LSG_TYP)
            {
                gvMain.SetRowCellValue(e.RowHandle, colSTP_LSG_X, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colSTP_LSG_Y, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colSTP_LSG_Z, DBNull.Value);
            }
        }

        private void lueTyp_EditValueChanged(object sender, EventArgs e)
        {
            string typ = lueTyp.EditValue.AsString();
            ActionLottoBase action = ActionLottoBase.GetAction(typ);
            if (action != null)
            {
                meTyp.Text = action.Opis.ReplaceSingleEOL();
            }
            else
            {
                meTyp.Text = "";
            }
        }

        private void gvMain_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DataRow row = gvMain.GetDataRow(e.FocusedRowHandle);
            if (row.CanRead())
            {
                lueTyp.EditValue = row["STP_LSG_TYP"].AsString();
            }
        }

    }
}
